import os
import base64
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
import sys
import re

def writeExtGradle(pluginName,aar_files):
    gradleContent = "dependencies {\n"
    for aarFile in aar_files:
        fileName = os.path.basename(aarFile)
        fileName = fileName[:fileName.rfind('.')]
        gradleContent += "  compile (name: '"+fileName+"', ext: 'aar')\n"     
    gradleContent += "  }\n"
    gradleContent += "repositories {\n"
    gradleContent += "  flatDir{\n"
    gradleContent += "      dirs 'src/main/libs'\n"
    gradleContent += "      }\n"
    gradleContent += "}\n"
    gradleContent += "ext.postBuildExtras = {\n"
    gradleContent += "  android {\n"
    gradleContent += "      compileOptions {\n"
    gradleContent += "          sourceCompatibility JavaVersion.VERSION_1_8\n"
    gradleContent += "          targetCompatibility JavaVersion.VERSION_1_8\n"
    gradleContent += "      }\n"
    gradleContent += "  allprojects {\n"
    gradleContent += "      compileOptions {\n"
    gradleContent += "          sourceCompatibility = JavaVersion.VERSION_1_8\n"
    gradleContent += "          targetCompatibility = JavaVersion.VERSION_1_8\n"
    gradleContent += "          }\n"
    gradleContent += "      }\n"
    gradleContent += "  }\n"
    gradleContent += "}\n"
    

    gradleFile = os.path.join(os.getcwd(),  pluginName,'src','android', 'build-extras.gradle')
    with open(gradleFile, 'w') as f:
        f.write(gradleContent)
        f.close()

def genExtGradle(pluginName,aar_files):
    for aar in aar_files:
        fileName = os.path.basename(aar)
        fileName = fileName[:fileName.rfind('.')]
    aar_contents = []
    if len(aar_files)>0:
        writeExtGradle(pluginName,aar_files)
        aar_contents.append('<source-file src="src/android/build-extras.gradle" target-dir="../../../" />\n')
    for aar in aar_files:
        fileName = os.path.basename(aar)
        fileName = fileName[:fileName.rfind('.')]
        aar_contents.append('<source-file src="src/android/aar/'+fileName+'.aar" target-dir="src/main/libs/" />')
        
    return aar_contents

def syncCordovaPluginAndroidSrc(pluginName):
    
    os.system("cat platforms/android/local.properties|grep ndk ||echo \"ndk.dir=$NDK_HOME\">>platforms/android/local.properties")
    os.system('cordova plugin|grep \"cordova-plugin-ry-Bridge\"&&cordova plugin remove cordova-plugin-ry-Bridge')
    java_src_dir = os.path.join(os.getcwd(), pluginName, 'src', 'android')
    java_src_files = []
    aar_files = []
    for (dir,_,files) in os.walk(java_src_dir):
        for file in files:
            if file.endswith('.java'):
                java_src_files.append(os.path.join(dir, file).removeprefix(java_src_dir+'/src/'))
            elif file.endswith('.aar'):
                aar_files.append(os.path.join(dir, file))
    java_src_conf_content = []
    for jf in java_src_files:
        
        dist_dir = jf[:jf.rfind('/')]
        content = '<source-file src="src/android/src/'+jf+'" target-dir="src/'+dist_dir+'" />'
        java_src_conf_content.append(content)
    aar_contests = []
    if len(aar_files)>0:
        print('gen build-extras.gradle file')
        aar_contests = genExtGradle(pluginName ,aar_files)    
    plugin_templ_file = os.path.join(os.getcwd(),  pluginName, 'plugin.tmpl.xml')
    
    lines = ''
    with open(plugin_templ_file, 'r') as f:
        lines = f.readlines()
        f.close()
    
    plugin_file = os.path.join(os.getcwd(),  pluginName, 'plugin.xml')
    with open(plugin_file, 'w') as f:
        for line in lines:
            if line.strip() == '<!-- java src start -->':
                for c in java_src_conf_content:
                    f.write(c+'\n')
                if len(aar_contests)>0:
                    f.write('\n')
                    for a in aar_contests:
                        print('gen -- '+ a)
                        f.write(a+'\n')
            else:
                f.write(line)
        f.close()




def read_aes_key():
    with open("aes.key", "rb") as f:
        key_base64 = f.read().strip()
    key = base64.b64decode(key_base64)
    print(f'key len {len(key)}')
    return key

def encrypt_file(key, input_file, output_file):
    with open(input_file, "rb") as f:
        plaintext = f.read()
        padder = padding.PKCS7(128).padder()
        padded_data = padder.update(plaintext)
        padded_data += padder.finalize()

        
        iv = b'0F102C9F71063130'  
        cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
        encryptor = cipher.encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()
        l = len(plaintext)
        print(f" plain text length {l}")
        
        with open(output_file, "wb") as ff:
            ff.write(ciphertext)
            ff.write(l.to_bytes(4, byteorder='big'))
            ff.close()
def decrypt_js_file():
    key = read_aes_key()
    js_dir = "www/js"
    data_dir = "www/data"
    if not os.path.exists(data_dir):
        os.makedirs(data_dir)
    i = 0
    for filename in os.listdir(js_dir):
        if filename.endswith(".js"):
            input_file = os.path.join(js_dir, filename)
            
            output_file = os.path.join(data_dir, f"{i}.d")
            i = i + 1
            encrypt_file(key, input_file, output_file)
            print(f"{filename} encrypted and saved to {output_file}")
    
    os.system(f"rm -rf {js_dir}")

    print("clean index.html...")
    with open("www/index.html", "r") as f:
        lines = f.readlines()
        
        pattern = r'<script\s+defer="defer"\s+[^>]*>.*?</script>'
        
        with open("www/index.html", "w") as ff:
            for i in range(len(lines)):
                line = lines[i]
                html_no_defer = re.sub(pattern, '', line)
                ff.write(html_no_defer)
            ff.close()
    
if __name__ == "__main__":
    
    if len(sys.argv) < 2:
        print("参数错误")
        sys.exit(1)
    if sys.argv[1] == "js":
        decrypt_js_file()
    elif sys.argv[1] == "xml":
        syncCordovaPluginAndroidSrc('cordova-plugin-rybridge')
    else:
        print("参数错误")
        sys.exit(1)